<?php

namespace app\qsapi\service;

use AlibabaCloud\SDK\Dypnsapi\V20170525\Dypnsapi;
use AlibabaCloud\SDK\Dypnsapi\V20170525\Models\GetMobileRequest;
use AlibabaCloud\Tea\Exception\TeaUnableRetryError;
use app\advertising\service\AsaService;
use app\common\controller\Kafka;
use app\common\controller\Sms;
use app\qsapi\model\BoxFirstLoginLog;
use app\qsapi\model\BoxHotAvatar;
use app\qsapi\model\BoxLoginLog;
use app\qsapi\model\BoxMemberInfo;
use app\qsapi\model\BoxMemberToken;
use app\qsapi\model\Member;
use Darabonba\OpenApi\Models\Config;
use think\cache\driver\Redis;
use think\Db;
use think\db\exception\DataNotFoundException;
use think\db\exception\ModelNotFoundException;
use think\Exception;
use think\exception\DbException;

class AuthorityService extends BaseService
{


    protected $send_type = [
        1 => 1,//登录,注册
        2 => 2,//修改密码
        3 => 3,//更换手机号
    ];

    /**
     * 发送验证码
     * @param $phone
     * @param $type
     * @return array
     */
    public function sendSms($phone, $type): array
    {
        if (empty($phone)) {
            return api_message([], '请输入手机号', 1);
        }
        if (!isset($this->send_type[$type])) {
            return api_message([], '短信类型错误', 1);
        }
        if (!preg_match('/^1[3456789]\d{9}$/', $phone)) {
            return api_message([], '手机号格式错误', 1);
        }
//        if (!$this->smsLimitSend($phone)) {
//            return api_message([], '发送频繁，请稍后再试', 1);
//        }
        $code = rand(100000, 999999);
        $res = (new Sms())->tencentSms($phone, $code, $type);
        if ($res['code'] == 0) {
            return api_message([], '发送成功');
        } else {
            return api_message([], $res['msg'] ?? '发送失败', 0);
        }
    }

    /**
     * Desc : 验证用户名和手机号是否属于同一个人,并发送短信
     * User : steven
     * Date : 2024-01-10 18:32
     * @param array $data
     * @return array
     */
    public function checkUserNameAndPhone(array $data = []): array
    {
        if (!isset($data['username']) || !$data['username'] || !isset($data['phone']) || !$data['phone']) {
            return api_message([], '请输入账号或者手机号', 0);
        }

        $is_mobile = is_mobile($data['phone']);
        if (!$is_mobile) {
            return api_message([], '请输入正确的手机号', 0);
        }

        $memberModel = new Member();
        $member_phone = $memberModel->getInfoByWhere(['phone' => $data['phone']]);
        if (empty($member_phone)) {
            return api_message([], '手机号未绑定任何账号!', -2);
        }
        if ($member_phone['username'] != $data['username']) {
            return api_message([], '手机号已绑定其他账号!', -3);
        }

        //发送验证码
        $postData = [
            'phone' => $data['phone'],
            'type'  => 3
        ];
        $result = curl_post(\think\facade\Env::get('domain.third_verification_url') . '/Authority/transfersendsms', $postData);
        $result = json_decode($result, true);
        if (isset($result['code']) && $result['code'] == 200) {
            return api_message([], '发送成功');
        } else {
            return api_message([], $result['msg'] ?? '发送失败', 1);
        }
    }

    /**
     * 账号密码登录
     * @param $data
     * @return array
     */
    public function loginByPass($data): array
    {
        if (!isset($data['username']) || !$data['username'] || !isset($data['password']) || !$data['password']) {
            return api_message([], '请输入账号或者密码', 0);
        }
        $is_mobile = is_mobile($data['username']);
        $memberModel = new Member();
        if($is_mobile){
            $member_info = $memberModel->getInfoByWhere(['phone' => $data['username'], 'mark' => 1]);
        }else{
            $member_info = $memberModel->getInfoByWhere(['username' => $data['username'], 'mark' => 1]);
        }
        if (!$member_info) {
            return api_message([], '账号不存在，请重新输入', -1);
        }
        if ($member_info['status'] == 0) {
            return api_message([], '账号被禁用，请重新输入', -1);
        }
        if (setMd5Pwd($data['password']) != $member_info['password']) {
            return api_message([], '密码不正确，请重新输入', -2);
        }

        $memberInfo = (new BoxMemberInfo())->where('member_id', $member_info['id'])->find();
        if (empty($memberInfo) && $member_info['source'] == 1 && $member_info['pid'] == 0) {
            (new MemberService())->initMemberInfo($member_info['id']);
        }

        // JWT生成token
        $jwt = new \Jwt();
        $token = $jwt->getToken($member_info['id']);
        // 结果返回
        $result = [
            'access_token' => $token,
        ];
        //统一返回
        $this->afterLogin($token, $member_info, $data);

        $redis = new Redis(getRedisConfig());
        $is_new = $redis->get('is_new_account:' . $member_info['id']);
        if (!empty($is_new)) {
            $result['is_new_account'] = 1;
        }
        $redis->rm('is_new_account:' . $member_info['id']);
        return api_message($result);
    }


    /**
     * 手机号验证码登录
     * @param $data
     * @return array
     */
    public function loginByPhone($data): array
    {
        if (!isset($data['phone']) || !$data['phone'] || !isset($data['code']) || !$data['code']) {
            return api_message([], '请输入手机或者验证码', 0);
        }
        $redis = new Redis(getRedisConfig());
        $redisData = $redis->get('phone_' . $data['phone'] . ':code_' . $data['code']);
        $redis->set('phone_' . $data['phone'] . ':code_' . $data['code'], 1, 1);
        if ($redisData) return api_message([], '请勿重复点击提交!', 1);
        //校验验证码
        $sms = new Sms();
        $res = $sms->smsVerify($data['phone'], $data['code']);
        if (!isset($res['code']) || $res['code'] != 0) {
            return api_message([], $res['msg'] ?? '验证码错误', 1);
        }

        $memberModel = new Member();
        $member_info = $memberModel->getInfoByWhere(['phone' => $data['phone'], 'mark' => 1]);
        if (!$member_info) {
            $member_info = $this->initMember($data['phone'], $data['device'] ?? '');
        }
        // JWT生成token
        $jwt = new \Jwt();
        $token = $jwt->getToken($member_info['id']);
        // 结果返回
        $result = [
            'access_token' => $token,
        ];
        //统一返回
        $this->afterLogin($token, $member_info);
        return api_message($result);
    }

    /***
     * 用户注册
     * @param $data
     * @return array
     */
    public function register($data): array
    {
        $username = $data['username'] ?? '';
        $password = $data['password'] ?? '';
        $re_password = $data['confirm_password'] ?? '';
        $device = $data['device'] ?? '';

        $redis = new Redis(getRedisConfig());
        $redisData = $redis->get('username_' . $username . ':password_' . $password);
        $redis->set('username_' . $username . ':password_' . $password, 1, 1);
        if ($redisData) return api_message([], '请勿重复提交!', 0);

        if (!$username) {
            return api_message([], '请输入账号', 0);
        }
        if (empty($password)) {
            return api_message([], '请输入密码', 0);
        }
        if ($password != $re_password) {
            return api_message([], '两次密码输入不一致，请重新输入', -3);
        }
        $checkUsername = validate_username_strength($username);
        $checkPassword = validate_password_strength($password);
        if (!$checkPassword && !$checkUsername) {
            return api_message([], '账号和密码不合法，请重新输入', -4);
        }
        if (!$checkPassword) {
            return api_message([], '密码不合法，请重新输入', -2);
        }
        if (!$checkUsername) {
            return api_message([], '账号不合法，请重新输入', -1);
        }
        $memberModel = new Member();
        $member_info = $memberModel->getInfoByWhere(['username' => $username]);
        if ($member_info) {
            return api_message([], '账号已存在，请重新输入', -5);
        }

        Db::startTrans();
        try {
            $res = $this->initMember('', $device, $username, $password);
            if (!$res['id']) {
                return api_message([], '注册失败，请重试', -6);
            }
            $redis->set('is_new_account:' . $res['id'], 1);

            Db::commit();
            return api_message([$res], '注册成功，欢迎使用');
        } catch (Exception $e) {
            Db::rollback();
            write_log('INFO', 'qsapi\service\AuthorityService.php', '用户名密码注册失败:' . $e->getMessage(), 'box_user_register', true);
            return api_message([], '注册失败，请重试', -6);
        }
    }


    /**
     * Desc : 验证手机验证码
     * User : you name
     * Date : 2024-01-10 19:33
     * @param string $phone
     * @param string $code
     * @param string $username
     * @return array
     */
    public function checkPhoneCode(string $phone = '', string $code = '', string $username = ''): array
    {
        if (!isset($username) || !$username) {
            return api_message([], '请输入用户名', 0);
        }
        if (!isset($phone) || !$phone) {
            return api_message([], '请输入手机号', 0);
        }
        if (!isset($code) || !$code) {
            return api_message([], '请输入验证码', 0);
        }
        $is_mobile = is_mobile($phone);
        if (!$is_mobile) {
            return api_message([], '请输入正确的手机号', 0);
        }
        $checkUsername = validate_username_strength($username);
        if (!$checkUsername) {
            return api_message([], '用户名不符合要求', 0);
        }

        $memberModel = new Member();
        $phone_info = $memberModel->getInfoByWhere(['phone' => $phone], 'username');
        if (!$phone_info) {
            return api_message([], '该手机号未绑定任何账号', -1);
        } else {
            if ($phone_info['username'] != $username) {
                return api_message([], '该手机号已绑定其他账号', -2);
            }
        }
        //该手机号已绑定其他它账号

        $sms = new Sms();
        $res = $sms->smsVerify($phone, $code);
        if (!isset($res['code']) || $res['code'] != 0) {
            return api_message([], $res['msg'] ?? '验证码错误', 1);
        }
        return api_message([], '验证通过');
    }

    /**
     * Desc : 重新设置密码
     * User : you name
     * Date : 2024-01-10 19:11
     * @param $data
     * @return array
     */
    public function resetPassword($data): array
    {
        if (!isset($data['phone']) || !$data['phone'] || !isset($data['username']) || !$data['username']) {
            return api_message([], '账号和手机号不能为空', 0);
        }
        $checkUsername = validate_username_strength($data['username']);
        if (!$checkUsername) {
            return api_message([], '账号不符合要求', 0);
        }
        $is_mobile = is_mobile($data['phone']);
        if (!$is_mobile) {
            return api_message([], '请输入正确的手机号', 0);
        }
        if (!isset($data['password']) || !$data['password']) {
            return api_message([], '请输入密码', 0);
        }
        if (!isset($data['confirm_password']) || !$data['confirm_password']) {
            return api_message([], '请输入确认密码', 0);
        }
        if ($data['password'] != $data['confirm_password']) {
            return api_message([], '两次输入密码不一致', -3);
        }
        $checkPassword = validate_password_strength($data['password']);
        if (!$checkPassword) {
            return api_message([], '密码强度不符合要求', -2);
        }
        $memberModel = new Member();
        $member_info = $memberModel->getInfoByWhere(['phone' => $data['phone']]);
        if (empty($member_info)) {
            return api_message([], '手机号不存在,请重新输入', -6);
        }
        if (!isset($member_info['username']) || empty($member_info['username'])) {
            return api_message([], '账号不存在,请重新输入', -5);
        }
        if ($data['username'] != $member_info['username']) {
            return api_message([], '账号和手机号不匹配', 0);
        }

        $where = ['phone' => $data['phone'], 'username' => $data['username']];
        $insertData = [
            'password'    => setMd5Pwd($data['password']),
            'update_time' => time()
        ];
        $res = $memberModel->update($insertData, $where);
        if (!$res) {
            return api_message([], '修改失败', -4);
        }
        return api_message([], '修改成功');
    }

    /**
     * 获取
     * @param $data
     * @return array
     */
    public function checkSms($data)
    {
        if (!isset($data['phone']) || !$data['phone'] || !isset($data['code']) || !$data['code']) {
            return api_message([], '请输入手机或者验证码', 0);
        }
        //校验验证码
        $sms = new Sms();
        $res = $sms->smsVerify($data['phone'], $data['code']);
        if (!isset($res['code']) || $res['code'] != 0) {
            return api_message([], $res['msg'] ?? '验证码错误', 1);
        }
        return api_message();
    }

    /**
     * 设置青少年模式
     * @return void
     */
    public function setAdolescent($member_id, $data)
    {
        if (!isset($data['status']) || !isset($data['password']) || !$data['password'] || !in_array($data['status'], [0, 1])) {
            return api_message([], '参数错误', 0);
        }
        $memberInfoModel = new BoxMemberInfo();
        $member_info = $memberInfoModel->getInfoByWhere(['member_id' => $member_id]);
        if (!$member_info) {
            return api_message([], '用户不存在', 0);
        }
        //关闭的时候  验证上次的密码
        $update_data['adolescent'] = $data['status'];
        $update_data['adolescent_pass'] = setMd5Pwd($data['password']);
        if ($data['status'] == 0) {
            if ($member_info['adolescent_pass'] != setMd5Pwd($data['password'])) {
                return api_message([], '密码不正确', 0);
            }
            $update_data['adolescent_pass'] = '';
        }
        $memberInfoModel->updateRow(['member_id' => $member_id], $update_data);
        return api_message();

    }

    /**
     * Desc : 补全登录日志
     * User : you name
     * Date : 2024-03-22 17:33
     * @param $member_id
     * @param $ip
     */
    public function addLoginLog($member_id, $ip, $device)
    {
        $redis = new Redis(getRedisConfig());
        $key = 'AddLoginLog:' . $member_id;
        $res = $redis->get($key);
        if (!$res && $member_id) {
            $member_info = (new Member())->getInfoByWhere(['id' => $member_id]);
            if ($member_info) {
                $this->setLoginLogPoint($member_info, $ip, 0, $device);
                $expire = strtotime(date('Y-m-d') . " 23:59:59") - time();
                $redis->set($key, 1, $expire);
            }
        }
    }

    /**
     * 登录后数据存储
     * @param $token
     *  $memberId  用户ID
     * @param $member
     * @return bool
     */
    public function afterLogin($token, $member): bool
    {
        $redis = new Redis([
                               'host'     => Env('redis.host'),
                               'port'     => Env('redis.port'),
                               'password' => Env('redis.password'),
                               'prefix = yun_phone_'
                           ]);
        //数据库存储信息
        $ip = get_client_ip();
        $memberToken = new BoxMemberToken();
        $memberId = $member['id'];
        //单点登录  只存单个信息
        $memberToken->insertRow([
                                    'member_id' => $memberId ?? 0,
                                    'token'     => $token,
                                    'ip'        => $ip,
                                    'add_time'  => time()
                                ]);
        //7天免登录
        return $redis->set($token, 1, 7 * 86400);
    }

    /**
     * 盒子登录成功日志的埋点接口
     */
    public function setLoginLogPoint($member, $ip, $promote_id = 0, $device = [])
    {
        try {
            //获取用户的注册时间
            $source = $member['source'];
            $promote_id = $this->promoteid;
            if (empty($promote_id)) {
                $promote_id = $member['promote_id'];
                $promote_account = $member['promote_account'];
            }
            $deviceName = $device['device'] ?? '';
            if (empty($deviceName)) {
                $deviceName = $this->getDeviceName() ?? '';
            }
            $area_info = ip2city($ip);
            $province = $area_info['province'] ?? '';
            $city = $area_info['city'] ?? '';
            $area = $area_info['area'] ?? '';
            $platform = $this->getPlatform() ?? '';
            $platform = $this->device[$platform] ?? 0;
            $regTime = time();
            $register_ip = $ip;
            //获取用户进入firstlog的时间
            $firstInfo = (new BoxFirstLoginLog())->where(['member_id' => $member['id']])->find();
            if (isset($firstInfo['login_time'])) {
                $regTime = $firstInfo['login_time'];
                $register_ip = $firstInfo['login_ip'];
            }
            $loginLogData = [
                'member_id'       => $member['id'],
                'reg_time'        => date('Y-m-d H:i:s', $regTime),
                'ip'              => $ip,
                'network'         => !empty($device['network']) ? json_decode('"' . $device['network'] . '"') : '',
                'net_isp'         => !empty($device['net_isp']) ? json_decode('"' . $device['net_isp'] . '"') : '',
                'sys_version'     => $device['sys_version'] ?? '',
                'sdk_version'     => $device['sdk_version'] ?? '',
                'device_name'     => $device['device_name'] ?? '',
                'port'            => $_SERVER['SERVER_PORT'] ?? '',
                'idfa'            => $device['idfa'] ?? '',
                'caid'            => $device['caid'] ?? '',
                'android_id'      => $device['android_id'] ?? '',
                'oaid'            => $device['oaid'] ?? '',
                'platform'        => $platform,
                'bundle_id'       => $device['bundle_id'] ?? $this->getPackname(),
                'promote_id'      => $promote_id,
                'register_source' => $source ?? 0,
                'device'          => $deviceName,
                'app_version'     => $this->getVersion() ?? '',
                'province'        => $province,
                'city'            => $city,
                'area'            => $area,
                'member_pid'      => 0,
                'type'            => $device['type'] ?? 1,
            ];
            $this->push_box_login_log($loginLogData);

            //推送主账号登陆日志
            $this->push_member_login_log(
                array(
                    'member_id'       => $member['id'],
                    'device'          => $deviceName,
                    'register_time'   => $regTime,
                    'promote_id'      => $promote_id,
                    'register_ip'     => $register_ip,
                    'promote_account' => $promote_account ?? '',
                    'port'            => $_SERVER['REMOTE_PORT'],
                    'idfa'            => $device['idfa'] ?? '',
                    'caid'            => $device['caid'] ?? '',
                    'android_id'      => $device['android_id'] ?? '',
                    'oaid'            => $device['oaid'] ?? '',
                    'device_name'     => $deviceName,
                    'sys_version'     => $device['sys_version'] ?? '',
                    'sdk_version'     => $this->getVersion() ?? '',
                    'app_version'     => $this->getVersion() ?? '',
                    'network'         => isset($device['network']) ? json_decode('"' . $device['network'] . '"') : '',
                    'net_isp'         => isset($device['net_isp']) ? json_decode('"' . $device['net_isp'] . '"') : '',
                    'platform'        => $platform,
                    'bundle_id'       => $device['bundle_id'] ?? $this->getPackname(),
                    'type'            => $device['type'] ?? 1,
                    'package_id'      => $device['package_id'] ?? 0,
                    'package_name'    => $device['package_name'] ?? '',
                )
            );
        } catch (\Exception $e) {
            write_log('INFO', 'AuthorityService.php', "数据库登录日志报错：" . json_encode($e->getMessage()), 'member_login_log', true);
        }

    }

    /**
     * 初始化用户member信息
     * @param   $phone
     * @param $device
     * @param string $name
     * @param string $password
     * @return array
     */
    public function initMember($phone, $device, string $name = '', string $password = ''): array
    {
        $memberModel = new Member();
        if (!empty($phone)) {
            //截取手机号后6位
            //username: 直接时间戳+随机数取个md5值，截取6位长度。
            $username = substr(md5(time() . rand(100000, 999999)), 0, 6) . substr($phone, -4);
            $nickname = '用户_' . substr($phone, -6);
            $member_info['username'] = $username;
            $member_info['nickname'] = $nickname;
        } else {
            $member_info['username'] = $name;
            $member_info['nickname'] = $name;
        }
        $member_info['phone'] = $phone ?? '';
        $member_info['device'] = $device ?? "";
        $member_info['avatar'] = $this->defaultAvatar();
        $member_info['source'] = 2;
        $member_info['register_ip'] = get_client_ip();
        $member_info['create_time'] = time();
        if (!empty($password)) {
            $member_info['password'] = setMd5Pwd($password);
        }
        $member_info['id'] = $memberModel->insertRow($member_info);
        (new MemberService())->initMemberInfo($member_info['id']);
        return $member_info;
    }

    /**
     * 推送用户注册日志
     * @return void
     */
    public function push_member_reg_log($data)
    {
        $platform = strtolower($this->platform) ?? '';
        switch ($platform) {
            case 'ios':
                $data['package_id'] = 9999998;
                $data['package_name'] = '千年游戏盒子(IOS版)';
                break;
            case 'android':
                $data['package_id'] = 9999999;
                $data['package_name'] = '千年游戏盒子(安卓版)';
                break;
            case 'pc':
                $data['package_id'] = 9999997;
                $data['package_name'] = '千年游戏盒子(PC版本)';
                break;
            default:
                $data['package_id'] = 9999999;
                $data['package_name'] = '千年游戏盒子';
                break;
        }
        $platform = empty($platform) ? 0 : $this->device[$platform];
        $logData = array(
            'member_id'       => $data['id'],
            'package_id'      => $data['package_id'],
            'package_name'    => $data['package_name'],
            'type'            => 1,
            'device'          => $data['device'],
            'device_name'     => $data['device_name'],
            'sys_version'     => $data['sys_version'],
            'sdk_version'     => $data['sdk_version'],
            'network'         => isset($device['network']) ? json_decode('"' . $device['network'] . '"') : '',
            'net_isp'         => isset($device['net_isp']) ? json_decode('"' . $device['net_isp'] . '"') : '',
            'register_time'   => $data['create_time'],
            'promote_id'      => $data['promote_id'],
            'register_ip'     => $data['register_ip'],
            'promote_account' => $data['promote_account'],
            'is_box'          => 1,
            'idfa'            => $data['idfa'] ?? '',
            'imei'            => $data['imei'] ?? '',
            'android_id'      => $data['android_id'] ?? '',
            'oaid'            => $data['oaid'] ?? '',
            'os'              => $data['os'] ?? '',
            'os_version'      => $data['os_version'] ?? '',
            'os_model'        => $data['os_model'] ?? '',
            'platform'        => $platform,
            'bundle_id'       => $data['bundle_id'] ?? '',
        );
        $kafka = new Kafka();
        $className = 'cqyq_register';
        $kafka->logProducer($className, $logData);
    }

    /**
     * 登录日志记录
     */
    public function push_member_login_log($data)
    {
        if (empty($data['package_id'])) {
            switch ($this->platform) {
                case 'ios':
                    $data['package_id'] = 9999998;
                    $data['package_name'] = '千年游戏盒子(IOS版)';
                    break;
                case 'android':
                    $data['package_id'] = 9999999;
                    $data['package_name'] = '千年游戏盒子(安卓版)';
                    break;
                case 'pc':
                    $data['package_id'] = 9999997;
                    $data['package_name'] = '千年游戏盒子(PC版本)';
                    break;
                default:
                    $data['package_id'] = 9999999;
                    $data['package_name'] = '千年游戏盒子';
                    break;
            }
            // $data['package_id'] = $this->platform == 'ios' ? 9999998 : 9999999;
            // $data['package_name'] = '千年游戏盒子';
        }
        $platform = $this->getPlatform() ?? '';
        $platform = $this->device[$platform] ?? 0;
        $logData = array(
            'member_id'       => $data['member_id'],
            'package_id'      => $data['package_id'],
            'package_name'    => $data['package_name'],
            'channel_id'      => 0,
            'login_ip'        => get_client_ip(),
            'type'            => $data['type'] ?? 1,
            'login_time'      => time(),
            'device'          => $data['device'] ?? $this->getDeviceName(),
            'register_time'   => $data['register_time'],
            'promote_id'      => $data['promote_id'],
            'register_ip'     => $data['register_ip'],
            'promote_account' => $data['promote_account'],
            'is_box'          => 1,
            'idfa'            => $data['idfa'] ?? '',
            'caid'            => $data['caid'] ?? '',
            'android_id'      => $data['android_id'] ?? '',
            'oaid'            => $data['oaid'] ?? '',
            'device_name'     => $data['device_name'],
            'sys_version'     => $data['sys_version'],
            'sdk_version'     => $data['sdk_version'],
            'network'         => isset($device['network']) ? json_decode('"' . $device['network'] . '"') : '',
            'net_isp'         => isset($device['net_isp']) ? json_decode('"' . $device['net_isp'] . '"') : '',
            'platform'        => $platform,
            'bundle_id'       => $data['bundle_id'] ?? '',
        );
        $kafka = new Kafka();
        $className = 'cqyq_login';
        $kafka->logProducer($className, $logData);
    }

    /**
     * Desc : 将用户的盒子登录或者注册日志推送到kafka
     * User : Steven
     * Date : 2024-06-18 15:11
     * @param $data
     */
    public function push_box_login_log($data)
    {
        $kafka = new Kafka();
        $className = 'cqyq_box_login';
        write_log('info', 'controller/BoxOverview.php', "kafaka消费数据过来了:" . json_encode($data), 'kafka_insert_box_login_log', true);
        $kafka->logProducer($className, $data);

    }

    /**
     * Desc : 首次登录日志
     * User : you name
     * Date : 2024-04-11 14:54
     * @param $device
     */
    public function push_member_first_login_log($device)
    {
        // $package_id     = $this->platform == 'ios' ? 9999998 : 9999999;
        // $package_name   = '千年游戏盒子';
        switch ($this->platform) {
            case 'ios':
                $package_id = 9999998;
                $package_name = '千年游戏盒子(IOS版)';
                break;
            case 'android':
                $package_id = 9999999;
                $package_name = '千年游戏盒子(安卓版)';
                break;
            case 'pc':
                $package_id = 9999997;
                $package_name = '千年游戏盒子(PC版本)';
                break;
            default:
                $package_id = 9999999;
                $package_name = '千年游戏盒子';
                break;
        }
        if ($device['type'] == 2) {
            $package_id = $device['package_id'] ?? 0;
            $package_name = $device['package_name'] ?? '';
        }
        $logData = array(
            'package_id'      => $package_id,
            'package_name'    => $package_name,
            'member_id'       => $device['member_id'] ?? 0,
            'promote_id'      => $device['promote_id'] ?? '',
            'promote_account' => $device['promote_account'] ?? '',
            'login_ip'        => $device['login_ip'],
            'type'            => $device['type'],
            'login_time'      => time(),
            'device'          => $device['device'] ?? '',
            'channel_id'      => $device['channel_id'] ?? '',
            'register_source' => $device['register_source'],
            'first_pay_time'  => 0,
            'sdk_version'     => $device['sdk_version'] ?? '',
            'network'         => $device['network'] ?? '',
            'net_isp'         => $device['net_isp'] ?? '',
            'sys_version'     => $device['sys_version'] ?? '',
            'device_name'     => $device['device_name'] ?? '',
            'port'            => $_SERVER['REMOTE_PORT'] ?? '',
            'idfa'            => $device['idfa'] ?? '',
            'caid'            => $device['caid'] ?? '',
            'android_id'      => $device['android_id'] ?? '',
            'oaid'            => $device['oaid'] ?? '',
            'platform'        => $device['platform'] ?? '',
            'bundle_id'       => $device['bundle_id'] ?? '',
        );
        $kafka = new Kafka();
//        write_log('info','AuthorityService.php',json_encode($logData),'set_kafka_product',true);
        $className = 'cqyq_box_first_login';
        $kafka->logProducer($className, $logData);
    }


    /**
     * 获取头像配置表中第一个头像值
     */
    public function defaultAvatar()
    {
        $redis = new Redis(getRedisConfig());
        $default = $redis->get('system_default_avatar');
        if (!$default) {
            $res = (new BoxHotAvatar())->field('icon')
                                       ->where('status', '=', 1)
                                       ->where('mark', '=', 1)
                                       ->where('is_default', '=', 1)
                                       ->order('id', 'desc')->find();
            $default = $res['icon'] ?? '';
        }
        return $default ?? '';
    }


    /**
     * @Notes:邀请活动用户注册
     */
    public function inviteRegister($phone, $device, $promote_id)
    {
        return $this->initMember($phone, $device, $promote_id);
    }

    /**
     * Desc : 验证用户是否存在
     * User : you name
     * Date : 2024-01-15 11:27
     * @param $param
     * @return array
     */
    public function checkUsername($param): array
    {
        if (empty($param['username'])) {
            return api_message([], '账号不能为空', 0);
        }
        $memberModel = new Member();
        $member_info = $memberModel->where('username', $param['username'])->field('id')->find();
        if (empty($member_info['id'])) {
            return api_message([], '账号不存在', 0);
        }
        return api_message([], '用户名存在', 200);
    }


    /**
     * 创蓝 一键登录
     * @param $token
     * @param $device
     * @param $device_params
     * @return array
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public function touchMobuieChuang($token, $device, $device_params): array
    {
        $flag = 1;
        $redis = new Redis(getRedisConfig());
        $redisData = $redis->get('chuang_phone:' . $token);
        $redis->set('chuang_phone:' . $token, 1, 1);
        if ($redisData) return api_message([], '请勿重复操作!', 0);

        if (!$token || !$this->packname) {
            return api_message([], '登录错误:缺少参数', 0);
        }
        $mobile_config = config('mobile.');
        if (!isset($mobile_config[$this->packname])) {
            return api_message([], '登录错误:配置错误', 0);
        }
        $url = 'https://api.253.com/open/flashsdk/mobile-query';
        $appId = $mobile_config[$this->packname]['appid'];
        $appKey = $mobile_config[$this->packname]['appkey'];
        $outId = time() . uniqid(); // 客户流水号
        $clientIp = request()->ip(); // 客户端IP
        $encryptType = '0'; // 加密方式：0 AES 1 RSA  ， 默认0 AES
        $content = 'appId' . $appId . 'clientIp' . $clientIp . 'encryptType' . $encryptType . 'outId' . $outId . 'token' . $token;
        $sign = bin2hex(hash_hmac('sha256', $content, $appKey, true));
        $params = [
            'appId'       => $appId,
            'token'       => $token,
            'outId'       => $outId,
            'clientIp'    => $clientIp,
            'encryptType' => $encryptType,
            'sign'        => $sign //签名
        ];
        $res = curl_post($url, $params);
        // Log::info('创蓝一键登录返回：' . $res);
        $res = json_decode($res, true);
        if (empty($res) || !isset($res['code']) || $res['code'] != 200000) {
            return api_message([], '登录错误', 0);
        }

        $mobile = $res['data']['mobileName']; // 手机号
        $key = md5($appKey);
        $phone = openssl_decrypt(hex2bin($mobile), 'AES-128-CBC', substr($key, 0, 16), OPENSSL_RAW_DATA, substr($key, 16));
        $memberModel = new Member();
        $member_info = $memberModel->getInfoByWhere(['phone' => $phone, 'mark' => 1]);
        $deviceInfo = $this->getDeviceInfo($device_params);
        if (!$member_info) {
            $redis = new Redis(getRedisConfig());
            $redisData = $redis->get('chuang_phone:' . $mobile);
            if (empty($redisData)) {
                $member_info = $this->initMember($phone, $device, $this->getPromoteId(), '', '', $deviceInfo);
                $is_new_account = 1;  //新用户的标识,配合广告投放使用
                //广告注册上报
                $device_params['member_id'] = $member_info['id'];
                $device_params['adid'] = $this->getPromoteId() ?? 0;
                (new BoxMediaAdService())->reportAdRedis($device_params, 2);

                //IOS接入ASA归因
                $device_params['asa_ctime'] = time();
                $device_params['event_type'] = 'register';
                AsaService::setRedisAsaInfo($device_params);
            }
            $redis->set('chuang_phone:' . $mobile, 1, 1);
            $flag = 2;
        }
        // JWT生成token
        $jwt = new \Jwt();
        $token = $jwt->getToken($member_info['id']);
        // 结果返回
        $result = [
            'access_token'   => $token,
            'is_new_account' => $is_new_account ?? 0
        ];

        if ($flag == 1) {
            //补充memberinfo
            $memberInfo = (new BoxMemberInfo())->where('member_id', $member_info['id'])->find();
            if (empty($memberInfo) && $member_info['source'] == 1 && $member_info['pid'] == 0) {
                (new MemberService())->initMemberInfo($member_info['id']);
                $promote_id = $this->getPromoteId();
                $promoteInfo = Db::name('user_promote')->where('id', $promote_id)->field('realname')->find();
                $promote_account = $promoteInfo['realname'] ?? '';
                $regIp = get_client_ip();
                $this->addMemberInfoAndFirstLoginLog($member_info['id'], $promote_id, $promote_account, $regIp, $deviceInfo);
            }
        }

        //统一返回
        $this->afterLogin($token, $member_info, $device_params);
        //判断SDK用户是否实名认证,如果实名认证给盒子用户默认增加积分
        @BoxTaskService::updateRealNameScore($member_info['id'], 1, $member_info['realname'] ?? '', $member_info['idcard'] ?? '');

        return api_message($result);
    }

    public function getDeviceInfo($data = []): array
    {
        $data['os'] = $data['platform'] ?? 0;
        $data['os_version'] = get_os_version() ?? '';
        return $data;
//        return [
//            'os'          => $data['platform'] ?? 0,
//            'idfa'        => $data['idfa'] ?? '',
//            'imei'        => $data['imei'] ?? '',
//            'android_id'  => $data['android_id'] ?? '',
//            'oaid'        => $data['oaid'] ?? '',
//            'caid'        => $data['caid'] ?? '',
//            'os_version'  => get_os_version() ?? '',
//            'os_model'    => $data['os_model'] ?? '',
//            'device_name' => $data['device_name'] ?? '',
//            'network'     => isset($data['network']) ? json_decode('"' . $data['network'] . '"') : '',
//            'net_isp'     => isset($data['net_isp']) ? json_decode('"' . $data['net_isp'] . '"') : '',
//            'bundle_id'   => $data['bundle_id'] ?? '',
//            'platform'    => $data['platform'] ?? 2
//        ];
    }

    /**
     * 限制发送短信
     */
    public function smsLimitSend($text, $redisKey = '', $redisKeyLimit = '', $redisDayKeyLimit = '')
    {
        $redis = new Redis(getRedisConfig());
        if (!$redisKey) {
            $redisKey = 'smsSend_' . $text;
        }
        if (!$redisKeyLimit) {
            $redisKeyLimit = 'smsLimitSend' . $text;
        }
        if (!$redisDayKeyLimit) {
            $redisDayKeyLimit = 'smsLimitSendDay' . $text;
        }
        //判断当日是否超过限制
        $dayLimit = $redis->get($redisDayKeyLimit, 0);
        if ($dayLimit > 10) return false;
        //获取小时发送次数
        $limit = $redis->get($redisKeyLimit, 0);
        if ($limit > 3) return false;
        //判断发送限制
        if ($redis->exists($redisKey)) {
            return false;
        }
        // 1分钟限制一条
        $redis->setex($redisKey, 60, $text);
        //一小时限制3条
        if ($redis->exists($redisKeyLimit)) {
            $limitTtl = $redis->ttl($redisKeyLimit);
            $redis->setex($redisKeyLimit, $limitTtl, $limit + 1);
        } else {
            $redis->setex($redisKeyLimit, 3600, $limit + 1);
        }
        if ($redis->exists($redisDayKeyLimit)) {
            $limitDayTtl = $redis->ttl($redisDayKeyLimit);
            $redis->setex($redisDayKeyLimit, $limitDayTtl, $dayLimit + 1);
        } else {
            //一天限制10条 获取剩余时间
            $ttl = strtotime(date('Y-m-d', strtotime('+ 1 day'))) - time();
            $redis->setex($redisDayKeyLimit, $ttl, $dayLimit + 1);
        }
        return $text;
    }


    public function addMemberInfoAndFirstLoginLog($memberId, $promote_id, $promote_account, $ip, $device)
    {
        try {
            $login_time = time();
            $platform = strtolower($this->platform) ?? '';
            // $platform = empty($platform) ? 0 : $this->device[$platform];
            $platform = $this->device[$platform] ?? 0;
            $this->push_member_first_login_log([
                                                   'member_id'       => $memberId,
                                                   'promote_id'      => $promote_id,
                                                   'promote_account' => $promote_account,
                                                   'login_ip'        => $ip,
                                                   'type'            => $device['type'] ?? 1, //账号类型 1= 主账号 2= 小号
                                                   'login_time'      => $login_time,
                                                   'device'          => $device['device'] ?? '',
                                                   'device_name'     => $device['device_name'] ?? '',
                                                   'channel_id'      => $device['channel_id'] ?? '',
                                                   'register_source' => $source['source'] ?? 2,
                                                   'first_pay_time'  => 0,
                                                   'sdk_version'     => $device['sdk_version'] ?? '',
                                                   'network'         => isset($device['network']) ? json_decode('"' . $device['network'] . '"') : '',
                                                   'net_isp'         => isset($device['net_isp']) ? json_decode('"' . $device['net_isp'] . '"') : '',
                                                   'sys_version'     => $device['sys_version'] ?? '',
                                                   'port'            => $_SERVER['SERVER_PORT'] ?? '',
                                                   'idfa'            => $device['idfa'] ?? '',
                                                   'caid'            => $device['caid'] ?? '',
                                                   'android_id'      => $device['android_id'] ?? '',
                                                   'oaid'            => $device['oaid'] ?? '',
                                                   'platform'        => $platform,
                                                   'bundle_id'       => $device['bundle_id'] ?? $this->getPackname(),
                                                   'app_version'     => $this->getVersion(),
                                                   'package_id'      => $device['package_id'] ?? '',
                                                   'package_name'    => $device['package_name'] ?? '',
                                               ]);
            return $login_time;
        } catch (Exception $e) {
            write_log('ERROR', 'qsapi\service\AuthorityService.php', '添加用户信息,和首次登录日志失败:' . json_encode($e->getMessage()), 'write_box_first_login_log', true);
        }

    }

    /**
     * Desc : 手机号修改密码
     * User : Steven
     * Date : 2024-07-29 10:03
     */
    public function phoneModifyPassword($member_id, $postData): array
    {
        $phone = $postData['phone'] ?? '';
        $password = $postData['password'] ?? '';
        $rePassword = $postData['rePassword'] ?? '';
        $code = $postData['code'] ?? '';
        if (empty($phone)) return api_message('', '手机号不能为空!', 0);
        if (empty($password)) return api_message('', '新密码不能为空!', 0);
        if (!validate_password_strength($password)) return api_message('', '新密码在6-20位字母或数字之间!', 0);
        if ($password !== $rePassword) return api_message('', '两次密码不相同!', 0);
        //校验验证码
        $sms = new Sms();
        $res = $sms->smsVerify($phone, $code);
        if (!isset($res['code']) || $res['code'] != 0) {
            return api_message([], $res['msg'] ?? '验证码错误', 1);
        }
        if(empty($member_id)){
            $member = Member::where('phone', '=', $phone)->field('phone,password')->find();
        }else{
            $member = Member::where('id', '=', $member_id)->field('phone,password')->find();
        }

        if (empty($member['phone'])) return api_message([], '手机号未绑定!', 0);
        if ($member['phone'] != $phone) return api_message([], '验证的手机号与当前账号绑定的手机号不一致,请返回上一步重新验证!', 0);
        $password = setMd5Pwd($password);
        if (!empty($member['password'])) {
            if ($member['password'] == $password) return api_message([], '新密码不能与旧密码相同!', 0);
        }
        $update = Member::where('phone', '=', $phone)->update(['password' => $password]);
        if ($update) {
            return api_message([], '密码设置成功!');
        } else {
            return api_message([], '密码设置失败,请重试!', 0);
        }
    }

    /**
     * Desc : 原密码修改密码
     * User : Steven
     * Date : 2024-07-29 10:54
     */
    public function passwordModify($member_id, $postData): array
    {
        $oldPassword = $postData['oldPassword'] ?? '';
        $newPassword = $postData['newPassword'] ?? '';
        $rePassword = $postData['reNewPassword'] ?? '';
        if (empty($oldPassword)) return api_message([], '原密码不能为空!', 0);
        if (empty($newPassword)) return api_message([], '新密码不能为空!', 0);
        if (empty($rePassword)) return api_message([], '确认新密码不能为空!', 0);

        if (!validate_password_strength($oldPassword)) return api_message([], '原密码在6-20位字母或数字之间!', 0);
        if (!validate_password_strength($newPassword)) return api_message([], '新密码在6-20位字母或数字之间!', 0);

        if ($newPassword !== $rePassword) return api_message([], '两次新密码不相同!', 0);

        $password = Member::where('id', '=', $member_id)->value('password');
        if ($password != setMd5Pwd($oldPassword)) return api_message([], '原密码错误!', 0);
        if ($password == setMd5Pwd($newPassword)) return api_message([], '新密码不能与旧密码相同!', 0);

        $update = Member::where('id', '=', $member_id)->update(['password' => setMd5Pwd($newPassword)]);
        if ($update) {
            return api_message([], '密码修改成功!');
        } else {
            return api_message([], '密码修改失败,请重试!', 0);
        }
    }

    /**
     * Desc : 账号注册绑定手机号
     * User : Steven
     * Date : 2024-07-29 14:48
     */
    public function bindMobile($member_id, $data): array
    {
        $phone = $data['phone'] ?? '';
        $code = $data['code'] ?? '';
        $username = $data['username'] ?? '';
        if (empty($phone)) return api_message('', '手机号不能为空!', 0);
        if (!is_mobile($phone)) return api_message('', '手机号格式错误!', 0);
        if (empty($code)) return api_message('', '验证码不能为空!', 0);
        if (empty($member_id)) return api_message('', '用户ID不能为空!', 0);
        if (empty($username)) return api_message('', '用户账号不能为空!', 0);

        $id = Member::where('phone', '=', $phone)->value('id');
        if (!empty($id) && $id > 0) return api_message('', '该手机号已被绑定!', 0);

        $sms = new Sms();
        $res = $sms->smsVerify($phone, $code);
        if (!isset($res['code']) || $res['code'] != 0) {
            return api_message('', $res['msg'] ?? '验证码错误', 1);
        }

        $memberInfo = Member::where('id', '=', $member_id)->field('username,phone')->find();
        $mobile = $memberInfo['phone'] ?? '';
        if (!empty($mobile)) return api_message('', '该用户已绑定手机号!', 0);
        $name = $memberInfo['username'] ?? '';
        if ($username != $name) return api_message('', '用户名与当前账号不一致!', 0);
        $result = Member::where('id', '=', $member_id)->update(['phone' => $phone]);
        if ($result) {
            return api_message('', '绑定成功!');
        } else {
            return api_message('', '绑定失败,请重试!', 0);
        }
    }

}
